package gee

import (
	"log"
	"net/http"
	"path"
)

type RouterGroup struct {
	prefix       string
	middileWares []HandlerFunc
	parent       *RouterGroup
	engine       *Engine
}

// add prefex for follow routers
func (group *RouterGroup) Group(prefix string) *RouterGroup {
	engine := group.engine
	newGroup := &RouterGroup{
		prefix: group.prefix + prefix,
		parent: group,
		engine: engine,
	}
	engine.groups = append(engine.groups, newGroup)
	return newGroup
}

// add router
func (group *RouterGroup) AddRouter(method string, pattern string, handleFunc HandlerFunc) {
	pattern = group.prefix + pattern
	log.Printf("Route %4s - %s", method, pattern)
	group.engine.AddRouter(method, pattern, handleFunc)
}

// add get router
func (group *RouterGroup) GET(pattern string, handleFunc HandlerFunc) {
	group.AddRouter("GET", pattern, handleFunc)
}

// add post router
func (group *RouterGroup) POST(pattern string, handleFunc HandlerFunc) {
	group.AddRouter("POST", pattern, handleFunc)
}

// use middleware
func (group *RouterGroup) Use(middileWares ...HandlerFunc) {
	group.middileWares = append(group.middileWares, middileWares...)
}

// add handler for static file
func (group *RouterGroup) createStaticHadler(relativePath string, fs http.FileSystem) HandlerFunc {
	absolutePath := path.Join(group.prefix, relativePath)
	filerServer := http.StripPrefix(absolutePath, http.FileServer(fs))
	return func(c *Context) {
		file := c.Param("filePath")
		if file == "" {
			c.SetStatusCode(http.StatusNotFound)
			return
		}
		// Check if file exists and/or if we have permission to access it
		if _, err := fs.Open(file); err != nil {
			c.SetStatusCode(http.StatusNotFound)
			return
		}
		filerServer.ServeHTTP(c.Res, c.Req)
	}
}

func (group *RouterGroup) Static(relativePath string, root string) {
	// get static handler
	handler := group.createStaticHadler(relativePath, http.Dir(root))
	//define a urlPattern for static
	urlPattern := path.Join(relativePath, "/*filePath")
	//register static router
	group.GET(urlPattern, handler)
}
